package sketch.specs;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import randoop.util.Files;
import sketch.util.Checker;

public class SymbolicFileParser {
	
	public final File file;
	
	public SymbolicFileParser(String fp) {
		file = new File(fp);
		Checker.checkTrue(file.exists(), "The file: " + fp + " does not exist!");
	}
	
	public Map<String, List<List<Integer>>> parseFile() throws IOException {
		Map<String, List<List<Integer>>> retMap = new LinkedHashMap<String, List<List<Integer>>>();
		List<String> content = Files.readWhole(file);
		boolean start = false;
		String testName = null;
		for(String line : content) {
			if(line.startsWith("#")) {
				testName = line.substring(line.lastIndexOf("_") + 1, line.indexOf("@"));
				retMap.put(testName, new LinkedList<List<Integer>>());
				start = true;
			} else {
				Checker.checkTrue(start, "The start should be true");
				Checker.checkNull(testName, "The test name should not be null");
				String[] values = line.split(",");
				List<Integer> list = new LinkedList<Integer>();
				for(String value : values) {
					Integer i = Integer.valueOf(value.trim());
					list.add(i);
				}
				retMap.get(testName).add(list);
			}
		}
		
		return retMap;
	}
	
	public static<T> List<List<T>> convertToNestedList(List<Map<String, T>> listMap) {
		List<List<T>> retList = new LinkedList<List<T>>();
		for(Map<String, T> map : listMap) {
			List<T> values = new LinkedList<T>();
			values.addAll(map.values());
			retList.add(values);
		}
		return retList;
	}
	
	public static<T1, T2> void checkTwoListValidity(List<List<T1>> list1, List<List<T2>> list2) {
		if(list1 == null && list2 == null) {
			Checker.fail("two lists can not be both null.");
		} else if (list1 == null && list2 != null) {
			checkListValid(list2);
		} else if (list1 != null && list2 == null) {
			checkListValid(list1);
		} else {
			checkListValid(list1);
			checkListValid(list2);
			Checker.checkTrue(list1.size() == list2.size(), "The length of two lists are not the same, one is: "
					+ list1.size() + ", the other is: " + list2.size());
		}
	}
	
	public static<T> void checkListValid(List<List<T>> lists) {
		if(lists != null) {
			if(lists.size() > 1) {
			  for(int i = 0; i < lists.size() - 1; i++) {
				 Checker.checkTrue(lists.get(i).size() == lists.get(i + 1).size(), "The list size should be equal, but " +
				 		"here the size of: " + i + " is: " + lists.get(i).size() + ", the next is: " + lists.get(i + 1).size());
			  }
			}
		}
	}
	
	public static<T> boolean hasContent(List<List<T>> lists) {
		if(lists == null) {
			return false;
		} else {
			for(List<T> list : lists) {
				if(list.isEmpty()) {
					return false;
				}
			}
		}
		return true;
	}
}